package com.dawn.module.hospital.service;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dawn.framework.common.enums.CommonStatusEnum;
import com.dawn.framework.common.pojo.CommonResult;
import com.dawn.framework.common.util.http.HttpUtils;
import com.dawn.framework.common.util.json.JsonUtils;
import com.dawn.framework.common.util.object.BeanUtils;
import com.dawn.module.hospital.config.CDBPayConfig;
import com.dawn.module.hospital.controller.admin.qrcodepay.vo.QrcodePaySaveReqVO;
import com.dawn.module.hospital.controller.app.order.vo.*;
import com.dawn.module.hospital.dal.dataobject.qrcodepay.QrcodePayDO;
import com.dawn.module.hospital.enums.BHConstants;
import com.dawn.module.hospital.enums.ErrorCodeConstants;
import com.dawn.module.hospital.enums.PayStatusEnum;
import com.dawn.module.hospital.model.pay.PayOrderCreateResModel;
import com.dawn.module.hospital.model.pay.bill.BillAbc;
import com.dawn.module.hospital.model.pay.bill.BillWx;
import com.dawn.module.hospital.service.qrcodepay.QrcodePayService;
import com.dawn.module.hospital.util.DateUtils;
import com.dawn.module.hospital.util.RandomUtils;
import com.dawn.module.system.api.dict.DictDataApi;
import com.dawn.module.system.api.dict.dto.DictDataRespDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @description:
 * @author: cnsu-cmh
 * @time: 2024/8/7 15:49
 */
@Slf4j
@Validated
@Service
public class OrderThirdService extends BHService {

    @Resource
    private RegisterService registerService;

    @Resource
    private OutpatientService outpatientService;

    @Autowired
    private CDBPayConfig payConfig;

    @Autowired
    private RefundService refundService;

    @Autowired
    private TemplateMsgService templateMsgService;

    @Resource
    private QrcodePayService qrcodePayService;

    @Resource
    private DictDataApi dictDataApi;

    public CommonResult refundChs(@Valid OrderRefundChsReqVO reqVO) {
        if(!payConfig.getWxChs().getMchNo().equals(reqVO.getUsername()) ||
                !payConfig.getWxChs().getAppid().equals(reqVO.getPassword()) ) {
            return CommonResult.error(ErrorCodeConstants.BH_ERROR.getCode(),"退款失败,接口用户信息验证失败");
        }
        String orderNumber = reqVO.getOrderNo();
        CDBPayUtils cdbPayUtils;
        CommonResult findResult = CommonResult.error(ErrorCodeConstants.BH_ERROR);
        String orderType = "";
        String orderName = "";
        if(orderNumber.indexOf("GH") != -1) {
            findResult = registerService.queryByOrderNumber(orderNumber);
            orderType = BHConstants.ORDER_TYPE_REG;
            orderName = "预约挂号";
        } else if (orderNumber.indexOf("JF") != -1 || orderNumber.indexOf("NAT") != -1 || orderNumber.indexOf("QR") != -1 || orderNumber.indexOf("HIV") != -1) {
            findResult = outpatientService.queryBillByOrderNumber(orderNumber);
            orderType = BHConstants.ORDER_TYPE_RECIPE;
            orderName = "门诊缴费";
        } else if (orderNumber.indexOf("ZYYJ") != -1) {
            orderType = BHConstants.ORDER_TYPE_PRE_PAYMENT;
            orderName = "住院预交";
        }
        if(findResult.isError()){
            return CommonResult.error(ErrorCodeConstants.BH_ERROR.getCode(),"退款失败,业务订单数据不存在");
        }

        Map findResultMap = (Map) findResult.getData();
        String openid = (String)findResultMap.get("userId");
        String patientName = String.valueOf(findResultMap.get("patientName"));
        String payScene = (String)findResultMap.get("payScene");
        String payType = "";
        if(payScene.equals(BHConstants.ALIPAY_MINI_APPLET.getMsg())){
            // 支付宝
            cdbPayUtils = CDBPayUtils.instance().build(CDBPayUtils.ALICHS);
            payType = CDBPayUtils.ALICHS;
        } else {
            cdbPayUtils = CDBPayUtils.instance().build(CDBPayUtils.WX_CHS);
            payType = CDBPayUtils.WX_CHS;
        }

        log.info("-------医保移动支付-退款-支付订单查询 orderNumber:"+orderNumber);
        CommonResult queryResult = cdbPayUtils.chsQuery(orderNumber);
        log.info("-------医保移动支付-退款-支付订单查询 payQueryResult-----json:"+ JsonUtils.toJsonString(queryResult));
        if(queryResult.isError()){
            return CommonResult.error(ErrorCodeConstants.BH_ERROR.getCode(),"退款失败,支付订单数据不存在");
        }

        JSONObject res = (JSONObject)queryResult.getData();
        JSONObject payOrder = res.getJSONObject("payOrder");
        JSONObject chsOrder = res.getJSONObject("chsOrder");
        int refundState = payOrder.getInteger("refundState");
        if(refundState == 2) {
            // 已退款
            CommonResult rqResult = cdbPayUtils.refundQuery(payOrder.getString("payOrderId"));
            log.info("-------医保移动支付-退款-支付订单查询 rqResult-----json:"+ JsonUtils.toJsonString(rqResult));

            if (rqResult.isSuccess()) {
                JSONArray refundArray = (JSONArray) rqResult.getData();
                JSONObject refundObject = refundArray.getJSONObject(0);
                Map re = new HashMap();
                re.put("REFUNDNO",refundObject.getString("mchRefundNo"));
                return CommonResult.success(re);
            }
        }

        Map refundMap = new HashMap();
        refundMap.put("patientName",patientName);
        refundMap.put("clinicNo",findResultMap.get("patientId"));
        refundMap.put("openid",openid);
        refundMap.put("des","HIS调用接口退费");
        refundMap.put("business",orderName);
        refundMap.put("orderNo",orderNumber);
        refundMap.put("seqNo",orderNumber);
        refundMap.put("totalCost",reqVO.getAmount());
        refundMap.put("operType","REFUND");

        String refundNo = "TF" + RandomUtils.buildRandomStr(4);
        CommonResult refundResult = doRefundChs(refundNo,reqVO,cdbPayUtils,payType,chsOrder);

        if(refundResult.isSuccess()) {
            try{
                templateMsgService.sendMsgRefund(orderType,findResultMap);

                refundMap.put("refundNo",refundNo);
                refundMap.put("status",0);
                refundService.saveRefundOrder(refundMap,orderType,orderNumber);
//                CommonResult saveResult = HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_SAVE_REFUND.getValue(), refundMap);
//                if(saveResult.isError()) {
//                    log.error("-------退款订单保存失败 refundMap-----"+JsonUtils.toJsonString(refundMap));
//                    log.error("-------退款订单保存失败 Message-----"+saveResult.getMsg());
//                }
            } finally {
                return CommonResult.success(new HashMap<String, String>(){{put("REFUNDNO",refundNo);}});
            }
        } else {
            return CommonResult.error(ErrorCodeConstants.BH_ERROR.getCode(),"退款失败:"+refundResult.getMsg());
        }
    }

    public CommonResult doRefundChs(String refundNo,OrderRefundChsReqVO reqVO,CDBPayUtils cdbPayUtils,String payType,JSONObject chsOrder) {
        Long totalFee = chsOrder.getLong("totalFee");
        BigDecimal totalFeeYuan = new BigDecimal(totalFee).divide(new BigDecimal(100));
        String totalCost = totalFeeYuan.setScale(2, BigDecimal.ROUND_HALF_UP).toString();

        Long cashFee = chsOrder.getLong("cashFee");
        Long amountL = new BigDecimal(reqVO.getAmount()).multiply(new BigDecimal(100)).longValue();

//        if(cashFee.compareTo(amountL) < 0) {
//            return CommonResult.error(ErrorCodeConstants.BH_ERROR.getCode(),"退费现金超过订单支付现金");
//        }

        HashMap<String,Object> chsParams = new HashMap();
        /*撤销流水号*/
        if(!StringUtils.isEmpty(reqVO.getCancelSerialNo())) {
            chsParams.put("cancelSerialNo",reqVO.getCancelSerialNo());
        }
        /*撤销单据号*/
        if(!StringUtils.isEmpty(reqVO.getCancelBillNo())) {
            chsParams.put("cancelBillNo",reqVO.getCancelBillNo());
        }
        /**
         * 部分退款
         * 非必填,不填则整单退款，CASH_ONLY则只退现金部分,
         * 现金跟医保可以分开退款，医保部分调中台【6203】接口退款。
         * */
        chsParams.put("partRefundType","CASH_ONLY");
        /**
         * 现金部分退款
         *
         * 不填默认全退，填写时则退指定金额，不能为0，
         * 仅当part_refund_type为空或CASH_ONLY时生效
         *
         * */
        chsParams.put("cashRefundFee",reqVO.getAmount());

        /**
         * 个账部分退款
         * 新版接口已删除 医保部分调中台【6203】接口退款。
         */
//            chsParams.put("insRefundFee","");

        /**
         * {”payOrdId” :”******”,”ref_reason”:”******”}
         * ref_reason退款原因
         * payOrdId: 对应处方上传的出参单号
         */
        String refundReason = "患者到窗口要求退费";
        if(!StringUtils.isEmpty(reqVO.getReason())) {
            refundReason = reqVO.getReason();
        }
        JSONObject requestContentJson = new JSONObject();
        requestContentJson.put("payOrdId",chsOrder.getString("payOrdId"));
        requestContentJson.put("ref_reason",refundReason);
        String requestContent = requestContentJson.toJSONString();
        chsParams.put("requestContent",requestContent);

        log.info("-------医保移动支付 发送退款请求-----");
        CommonResult refundResult = CommonResult.error(ErrorCodeConstants.BH_ERROR.getCode(),"退款操作失败");

        if(payType.equals(CDBPayUtils.ALICHS)){
            refundResult =  cdbPayUtils.refundOrder(reqVO.getOrderNo(),refundNo,totalCost,"HIS调用接口退费,电脑IP:" + reqVO.getClientIp());
        }else {
            refundResult =  cdbPayUtils.chsRefundOrder(reqVO.getOrderNo(),refundNo,totalCost,"HIS调用接口退费,电脑IP:" + reqVO.getClientIp(),chsParams);
        }
        log.info("-------医保移动支付 退款结果-----refundResult:"+JsonUtils.toJsonString(refundResult));

        if(refundResult.isError()){
            return refundResult;
        }

//        JSONObject refundInfo = (JSONObject)refundResult.getData();
        refundResult = CommonResult.success(new HashMap<String, String>(){{put("REFUNDNO",refundNo);}});
        return refundResult;
    }

    public CommonResult refund(@Valid OrderRefundReqVO reqVO) {
        if(!payConfig.getAbc().getMchNo().equals(reqVO.getUsername()) ||
                !payConfig.getAbc().getAppid().equals(reqVO.getPassword()) ) {
            return CommonResult.error(ErrorCodeConstants.BH_ERROR.getCode(),"退款失败,接口用户信息验证失败");
        }
        String orderNumber = reqVO.getOrderNo();

        CDBPayUtils cdbPayUtils;
        CommonResult findResult = CommonResult.error(ErrorCodeConstants.BH_ERROR);
        String orderType = "";
        String orderName = "";
        if(orderNumber.indexOf("GH") != -1) {
            findResult = registerService.queryByOrderNumber(orderNumber);
            orderType = BHConstants.ORDER_TYPE_REG;
            orderName = "预约挂号";
        } else if (orderNumber.indexOf("JF") != -1 || orderNumber.indexOf("NAT") != -1 || orderNumber.indexOf("QR") != -1 || orderNumber.indexOf("HIV") != -1) {
            findResult = outpatientService.queryBillByOrderNumber(orderNumber);
            orderType = BHConstants.ORDER_TYPE_RECIPE;
            orderName = "门诊缴费";
        } else if (orderNumber.indexOf("ZYYJ") != -1) {
            orderType = BHConstants.ORDER_TYPE_PRE_PAYMENT;
            orderName = "住院预交";
        } else if (orderNumber.indexOf("QAC") != -1) {
            findResult = qrcodePayService.queryPay(orderNumber);
            orderType = BHConstants.AUTH_CODE_PAY_WX.getMsg();
            orderName = BHConstants.AUTH_CODE_PAY_WX.getMsg();
        } else {
            findResult = qrcodePayService.queryPay(orderNumber);
            orderType = BHConstants.AUTH_CODE_PAY_WX.getMsg();
            orderName = BHConstants.AUTH_CODE_PAY_WX.getMsg();
        }
        if(findResult.isError()){
            return CommonResult.error(ErrorCodeConstants.BH_ERROR.getCode(),"退款失败,业务订单数据不存在");
        }

        Map findResultMap = (Map) findResult.getData();
        String openid = (String)findResultMap.get("userId");
        String patientName = String.valueOf(findResultMap.get("patientName"));
        String payScene = (String)findResultMap.get("payScene");
        if(payScene.equals(BHConstants.ALIPAY_MINI_APPLET.getMsg())){
            // 支付宝
            cdbPayUtils = CDBPayUtils.instance().build(CDBPayUtils.ALI);
        } else {
            cdbPayUtils = CDBPayUtils.instance().build(CDBPayUtils.WX);
        }

        log.info("-------退款-支付订单查询 orderNumber:"+orderNumber);
        CommonResult queryResult = cdbPayUtils.query(orderNumber);
        log.info("-------退款-支付订单查询 payQueryResult-----json:"+ JsonUtils.toJsonString(queryResult));
        if(queryResult.isError()){
            return CommonResult.error(ErrorCodeConstants.BH_ERROR.getCode(),"退款失败,支付订单数据不存在");
        }

        JSONObject payOrder = (JSONObject)queryResult.getData();
        int refundState = payOrder.getInteger("refundState");
        if(refundState == 2) {
            // 已退款
            CommonResult rqResult = cdbPayUtils.refundQuery(payOrder.getString("payOrderId"));
            if (rqResult.isSuccess()) {
                JSONArray refundArray = (JSONArray) rqResult.getData();
                JSONObject refundObject = refundArray.getJSONObject(0);

                Map re = new HashMap();
                re.put("REFUNDNO",refundObject.getString("mchRefundNo"));
                return CommonResult.success(re);
            }
        }

        Map refundMap = new HashMap();
        refundMap.put("patientName",patientName);
        refundMap.put("clinicNo",findResultMap.get("patientId"));
        refundMap.put("openid",openid);
        if(StringUtils.hasLength(reqVO.getDes())){
            refundMap.put("des",reqVO.getDes());
        }else {
            refundMap.put("des","HIS调用接口退费");
        }
        refundMap.put("business",orderName);
        refundMap.put("orderNo",orderNumber);
        refundMap.put("seqNo",orderNumber);
        refundMap.put("totalCost",reqVO.getRefundFee());
        refundMap.put("operType","REFUND");

        String refundNo = "TF" + RandomUtils.buildRandomStr(4);
        CommonResult refundResult = cdbPayUtils.refundOrder(orderNumber, refundNo, reqVO.getRefundFee(), "HIS调用接口退费,电脑IP:" + reqVO.getClientIp());

        if(refundResult.isSuccess()) {
            try{
                templateMsgService.sendMsgRefund(orderType,findResultMap);

                refundMap.put("refundNo",refundNo);
                refundMap.put("status",0);
                refundService.saveRefundOrder(refundMap,orderType,orderNumber);
//                CommonResult saveResult = HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_SAVE_REFUND.getValue(), refundMap);
//                if(saveResult.isError()) {
//                    log.error("-------退款订单保存失败 refundMap-----"+JsonUtils.toJsonString(refundMap));
//                    log.error("-------退款订单保存失败 Message-----"+saveResult.getMsg());
//                }
            } finally {
                return CommonResult.success(new HashMap<String, String>(){{put("REFUNDNO",refundNo);}});
            }
        } else {
            return CommonResult.error(ErrorCodeConstants.BH_ERROR.getCode(),"退款失败:"+refundResult.getMsg());
        }
    }


    public CommonResult getQrURL(@Valid OrderThirdQRReqVO reqVO) {
        if (!payConfig.getAbc().getMchNo().equals(reqVO.getUsername()) ||
                !payConfig.getAbc().getAppid().equals(reqVO.getPassword())) {
            return CommonResult.error(ErrorCodeConstants.BH_ERROR.getCode(), "获取处方二维码失败,接口用户信息验证失败");
        }

        QrcodePaySaveReqVO qrcodePaySaveReqVO = new QrcodePaySaveReqVO();
        String orderNumber = "QP" + RandomUtils.buildRandomStr(4);
        qrcodePaySaveReqVO.setOrderNumber(orderNumber);
        qrcodePaySaveReqVO.setAmount(new BigDecimal(0));
        qrcodePaySaveReqVO.setPatientId(reqVO.getPatientId());
        qrcodePaySaveReqVO.setPatientName(reqVO.getPatientName());
        qrcodePaySaveReqVO.setIdCardNo(reqVO.getIdCardNo());
        qrcodePaySaveReqVO.setClinicNo(reqVO.getClinicNo());
        qrcodePaySaveReqVO.setOrderType(BHConstants.PRESCRIPTIONS_QR_CODE.getMsg());
        qrcodePaySaveReqVO.setQrcodeUrl(getTemplateMsgCfg().getRootUrl()+"hosp/qrcode/prescription?orderId="+orderNumber);
        qrcodePaySaveReqVO.setRemark(reqVO.getClientIp());

        Long id = qrcodePayService.createQrcodePay(qrcodePaySaveReqVO);
        QrcodePayDO qrcodePayDO = qrcodePayService.getQrcodePay(id);

        Map<String, String> qrCodeMap = new HashMap<>();
        qrCodeMap.put("qrCode",qrcodePayDO.getQrcodeUrl());

        return CommonResult.success(qrCodeMap);

    }

    public CommonResult authCodePay(@Valid OrderThirdAuthCodeReqVO reqVO) {
        if (!payConfig.getAbc().getMchNo().equals(reqVO.getUsername()) ||
                !payConfig.getAbc().getAppid().equals(reqVO.getPassword())) {
            return CommonResult.error(ErrorCodeConstants.BH_ERROR.getCode(), "付款码支付失败,接口用户信息验证失败");
        }

        QrcodePayDO qrcodePayOld = qrcodePayService.getQrcodePayByHisOrderNo(reqVO.getOrderNo());
        if(qrcodePayOld != null && qrcodePayOld.getPayStatus() == 2){
            return CommonResult.error(ErrorCodeConstants.BH_ERROR.getCode(), "付款码支付失败,HIS系统订单号重复");
        }

        String tradeItem = "";
        if(BHConstants.ORDER_TYPE_REG.equals(reqVO.getOrderType())){
            tradeItem = "挂号";
        }else if (BHConstants.ORDER_TYPE_RECIPE.equals(reqVO.getOrderType())){
            tradeItem = "缴费";
        }else if (BHConstants.ORDER_TYPE_PRE_PAYMENT.equals(reqVO.getOrderType())){
            tradeItem = "住院预交";
        }

        BHConstants.CS payConstants = BHConstants.AUTH_CODE_PAY_WX;
        String payWay = CDBPayUtils.ABC;
        String authCode = reqVO.getAuthCode();
        int prefix = Integer.parseInt(authCode.substring(0, 2));
        if(authCode.length() == 18 &&  prefix >=10 &&  prefix <= 15) {
            payConstants = BHConstants.AUTH_CODE_PAY_WX;
            payWay = CDBPayUtils.WX;
        } else if(authCode.length() >= 16 && authCode.length() <= 24 && prefix >=25 &&  prefix <= 30) {
            payConstants = BHConstants.AUTH_CODE_PAY_ALI;
            payWay = CDBPayUtils.ALI;
        } else {
            payConstants = BHConstants.AUTH_CODE_PAY_ABC;
            payWay = CDBPayUtils.ABC;
        }

        QrcodePaySaveReqVO qrcodePaySaveReqVO = new QrcodePaySaveReqVO();
        String orderNumber = "QAC" + RandomUtils.buildRandomStr(4);
        qrcodePaySaveReqVO.setPayTypeId(payConstants.getCode());
        qrcodePaySaveReqVO.setPayModeName(payConstants.getValue());
        qrcodePaySaveReqVO.setTitle(payConstants.getMsg()+'-'+tradeItem);

        qrcodePaySaveReqVO.setPayScene(payConstants.getMsg());

        qrcodePaySaveReqVO.setOrderNumber(orderNumber);
        qrcodePaySaveReqVO.setPatientId(reqVO.getPatientId());
        qrcodePaySaveReqVO.setPatientName(reqVO.getPatientName());
        qrcodePaySaveReqVO.setIdCardNo(reqVO.getIdCardNo());
        qrcodePaySaveReqVO.setClinicNo(reqVO.getClinicNo());
        qrcodePaySaveReqVO.setOrderType(reqVO.getOrderType());
        qrcodePaySaveReqVO.setHisOrderNo(reqVO.getOrderNo());
        qrcodePaySaveReqVO.setAuthCode(reqVO.getAuthCode());
        qrcodePaySaveReqVO.setAmount(new BigDecimal(reqVO.getAmount()));
        qrcodePaySaveReqVO.setHisBillNos(reqVO.getBillNos());
        qrcodePaySaveReqVO.setRemark(reqVO.getClientIp());

        Long id = qrcodePayService.createQrcodePay(qrcodePaySaveReqVO);
        QrcodePayDO qrcodePayDO = qrcodePayService.getQrcodePay(id);

        String body = CDBPayUtils.packageBody(qrcodePayDO.getPatientId(),
                qrcodePayDO.getPatientName(),
                qrcodePayDO.getHisOrderNo(),
                qrcodePayDO.getIdCardNo(),qrcodePayDO.getHisBillNos());

        BigDecimal totalCostB = qrcodePayDO.getAmount();
        String orderTitle = qrcodePayDO.getTitle()+"("+qrcodePayDO.getHisOrderNo()+")";

        CommonResult payResult = CDBPayUtils.instance().build(payWay)
                .barPay(orderNumber,orderTitle,totalCostB.setScale(2, BigDecimal.ROUND_HALF_UP).toString(),
                        body, qrcodePayDO.getAuthCode());
        log.warn("-------付款码支付下单 payResult-----json:"+ JsonUtils.toJsonString(payResult));
        if(payResult.isError()) {
            qrcodePaySaveReqVO.setId(qrcodePayDO.getId());
            qrcodePaySaveReqVO.setPayStatus(PayStatusEnum.PAY_STATUS_FAIL.getCode());
            qrcodePaySaveReqVO.setRemark(payResult.getMsg());
            qrcodePayService.updateQrcodePay(qrcodePaySaveReqVO);
            return payResult;
        }
        JSONObject resData = (JSONObject)payResult.getData();
        PayOrderCreateResModel payOrderCreateResModel = JSONObject.toJavaObject(resData,PayOrderCreateResModel.class);
        Integer orderState = payOrderCreateResModel.getOrderState();

        OrderThirdAuthCodeRespVO respVO = new OrderThirdAuthCodeRespVO(qrcodePayDO.getHisOrderNo(),qrcodePayDO.getOrderNumber(),payOrderCreateResModel.getPayOrderId()
                ,qrcodePayDO.getThirdOrderNo(),qrcodePayDO.getAmount().toString(),PayStatusEnum.PAY_STATUS_CREATE.getCode(),qrcodePayDO.getPayTypeId(),qrcodePayDO.getPayModeName());

        QrcodePaySaveReqVO qrcodePayUpdateReqVO = BeanUtils.toBean(qrcodePayDO,QrcodePaySaveReqVO.class);
        qrcodePayUpdateReqVO.setPayOrderId(payOrderCreateResModel.getPayOrderId());
        qrcodePayUpdateReqVO.setPayStatus(PayStatusEnum.PAY_STATUS_CREATE.getCode());
        if(orderState == PayStatusEnum.PAY_STATUS_PAYOFF.getCode()){
            qrcodePayUpdateReqVO.setPayStatus(PayStatusEnum.PAY_STATUS_PAYOFF.getCode());
            qrcodePayUpdateReqVO.setPayTime(LocalDateTime.now());
        }
        qrcodePayService.updateQrcodePay(qrcodePayUpdateReqVO);

        log.warn("-------付款码支付下单 respVO-----json:"+ JsonUtils.toJsonString(respVO));
        return CommonResult.success(respVO);

    }

    public CommonResult payQuery(@Valid OrderThirdQueryReqVO reqVO) {
        if (!payConfig.getAbc().getMchNo().equals(reqVO.getUsername()) ||
                !payConfig.getAbc().getAppid().equals(reqVO.getPassword())) {
            return CommonResult.error(ErrorCodeConstants.BH_ERROR.getCode(), "订单信息查询失败,接口用户信息验证失败");
        }

        QrcodePayDO qrcodePayDO = qrcodePayService.getQrcodePayByHisOrderNo(reqVO.getOrderNo());
        if(qrcodePayDO == null){
            return CommonResult.error(ErrorCodeConstants.BH_ERROR.getCode(), "未查询到订单记录");
        }

        OrderThirdQueryRespVO respVO = new OrderThirdQueryRespVO(qrcodePayDO.getHisOrderNo(),qrcodePayDO.getOrderNumber(),qrcodePayDO.getPayOrderId()
                ,qrcodePayDO.getThirdOrderNo(),qrcodePayDO.getAmount().toString(),qrcodePayDO.getPayStatus(),qrcodePayDO.getPayTypeId(),qrcodePayDO.getPayModeName());

        if(qrcodePayDO.getPayStatus() == PayStatusEnum.PAY_STATUS_PAYOFF.getCode()
                || qrcodePayDO.getPayStatus() == PayStatusEnum.PAY_STATUS_REFUND.getCode()){
            return CommonResult.success(respVO);
        }

        CDBPayUtils cdbPayUtils = CDBPayUtils.instance().build(CDBPayUtils.WX);
        if(BHConstants.AUTH_CODE_PAY_WX.getValue().equals(qrcodePayDO.getPayModeName())){
            cdbPayUtils = CDBPayUtils.instance().build(CDBPayUtils.WX);
        } else if (BHConstants.AUTH_CODE_PAY_ALI.getValue().equals(qrcodePayDO.getPayModeName())) {
            cdbPayUtils = CDBPayUtils.instance().build(CDBPayUtils.ALI);
        } else if (BHConstants.AUTH_CODE_PAY_ABC.getValue().equals(qrcodePayDO.getPayModeName())) {
            cdbPayUtils = CDBPayUtils.instance().build(CDBPayUtils.ABC);
        } else {
            cdbPayUtils = CDBPayUtils.instance().build(CDBPayUtils.WX);
        }


        CommonResult payResult = cdbPayUtils.query(qrcodePayDO.getOrderNumber());
        log.warn("-------订单查询 payQueryResult-----json:"+ JsonUtils.toJsonString(payResult));
        if(payResult.isSuccess()) {
            JSONObject res = (JSONObject)payResult.getData();
            Integer orderState = res.getInteger("state");
            respVO.setOrderState(orderState);

            QrcodePaySaveReqVO qrcodePayUpdateReqVO = BeanUtils.toBean(qrcodePayDO,QrcodePaySaveReqVO.class);
            qrcodePayUpdateReqVO.setPayOrderId(res.getString("payOrderId"));
            qrcodePayUpdateReqVO.setPayStatus(orderState);
            if(orderState == PayStatusEnum.PAY_STATUS_PAYOFF.getCode()){
                qrcodePayUpdateReqVO.setPayTime(LocalDateTimeUtil.parse(res.getString("successTime"), DatePattern.NORM_DATETIME_PATTERN));
                qrcodePayUpdateReqVO.setThirdOrderNo(res.getString("channelOrderNo"));
            }
            respVO.setOrderNumber(qrcodePayDO.getOrderNumber());
            respVO.setPayOrderId(qrcodePayDO.getPayOrderId());
            respVO.setThirdOrderNo(qrcodePayUpdateReqVO.getPayOrderId());
            respVO.setOrderState(qrcodePayUpdateReqVO.getPayStatus());
            qrcodePayService.updateQrcodePay(qrcodePayUpdateReqVO);
        }

        return CommonResult.success(respVO);

    }

    public CommonResult billDownload(@Valid OrderThirdBillDownloadReqVO reqVO) {
        if (!payConfig.getAbc().getAppid().equals(reqVO.getAppId())) {
            return CommonResult.error(ErrorCodeConstants.BH_ERROR.getCode(), "账单下载失败,接口信息验证失败");
        }

        JSONArray array = new JSONArray();
        List<DictDataRespDTO> dictDataList = dictDataApi.getDictDataList(BHConstants.DICT_RECON_BILL_DOWNLOAD);
        if(dictDataList!=null && dictDataList.size()>0){
            for (DictDataRespDTO dictData : dictDataList) {
                if(dictData.getStatus() == CommonStatusEnum.ENABLE.getStatus()){
                    Map<String, Object> requestBody = new HashMap<>();
                    requestBody.put("payCenterAppId",dictData.getValue());
                    requestBody.put("beginDate",reqVO.getBillDate());
                    requestBody.put("endDate",reqVO.getBillDate());
                    String billType = dictData.getRemark();
                    requestBody.put("billType",billType);

                    String url = payConfig.getUrl() + BHConstants.QUERY_RECON_BILL_LIST.getValue();
                    CommonResult httpResult = HttpUtils.postForm(url,requestBody);
                    if(httpResult.isSuccess()) {
                        JSONArray jsonArray = (JSONArray)httpResult.getData();
                        if("abc".equals(billType)){
                            List<BillAbc> billAbcList = BeanUtils.toBean(jsonArray, BillAbc.class);
                            array.addAll(billAbcList);
                        } else if ("wx".equals(billType)) {
                            List<BillWx> billWxList = BeanUtils.toBean(jsonArray, BillWx.class);
                            if(billWxList!=null && billWxList.size()>0){
                                List<BillAbc> abcList = new ArrayList<>();
                                for (BillWx wx : billWxList) {
                                    BillAbc billAbc = BeanUtils.toBean(wx,BillAbc.class);
                                    billAbc.setTradeDate(DateUtils.formatDate(DateUtils.parseDate(wx.getTradeTime()),"yyyyMMdd"));
                                    billAbc.setFeeType(wx.getBankType());
                                    billAbc.setSubject(wx.getBody());
                                    billAbc.setSettlementTotalFee(wx.getTotalFee());
                                    if("REFUND".equals(wx.getTradeState())){
                                        billAbc.setTradeType("WeiXinMicroPayRefund");
                                        billAbc.setOutTradeNo(wx.getOutRefundNo());
                                        billAbc.setOutRefundNo(wx.getOutTradeNo());
                                        billAbc.setTotalFee(wx.getRefundFee());
                                        billAbc.setSettlementTotalFee(wx.getRefundFee());
                                    }else if ("SUCCESS".equals(wx.getTradeState())){
                                        billAbc.setTradeType("WeiXinMicroPay");
                                    }
                                    abcList.add(billAbc);
                                }
                                array.addAll(abcList);
                            }
                        }
                    }
                }
            }
        }
        if(array.size() > 0){
            return CommonResult.success(array);
        }else {
            return CommonResult.error(ErrorCodeConstants.BH_ERROR.getCode(), "未查询到账单数据");
        }
    }


}
